package com.hycat.mail.member.service.impl;

import com.hycat.mail.common.exception.MailException;
import com.hycat.mail.common.model.ExceptionEnum;
import com.hycat.mail.common.model.JwtInfo;
import com.hycat.mail.common.utils.*;
import com.hycat.mail.member.vo.LoginParam;
import com.hycat.mail.member.vo.RegisterParam;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import java.util.Map;
import java.util.Objects;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import com.hycat.mail.member.dao.MemberDao;
import com.hycat.mail.member.entity.MemberEntity;
import com.hycat.mail.member.service.MemberService;


@Service("memberService")
public class MemberServiceImpl extends ServiceImpl<MemberDao, MemberEntity> implements MemberService {
    @Autowired
    private RedisTemplate redisTemplate;

    private static final String SMS_SIGN = "smsRegister:";

    @Override
    public PageUtil queryPage(Map<String, Object> params) {
        IPage<MemberEntity> page = this.page(
                new Query<MemberEntity>().getPage(params),
                new QueryWrapper<MemberEntity>()
        );

        return new PageUtil(page);
    }

    @Override
    public void register(RegisterParam registerParam) {
        String code = registerParam.getCode();
        String mobile = registerParam.getMobile();
        String username = registerParam.getUsername();
        verifyCode(mobile, code);
        boolean verifyMobile = verifyMobile(mobile);
        boolean verifyUserName = verifyUserName(username);

        if(!verifyMobile) {
            throw new MailException(ExceptionEnum.MEMBER_MOBILE_EXIST);
        }
        if(!verifyUserName) {
            throw new MailException(ExceptionEnum.MEMBER_USERNAME_EXIST);
        }
        redisTemplate.delete(SMS_SIGN + mobile);
        MemberEntity memberEntity = MemberEntity.from(registerParam);
        save(memberEntity);

    }

    @Override
    public String login(LoginParam loginParam) {
        String userInfo = loginParam.getUserInfo();
        String password = loginParam.getPassword();
        QueryWrapper<MemberEntity> wrapper = new QueryWrapper<MemberEntity>();

        wrapper.eq("mobile", userInfo).or().eq("username", userInfo);
        MemberEntity member = this.getOne(wrapper);
        if(Objects.isNull(member)) {
            throw new MailException(ExceptionEnum.MEMBER_USERINFO_NOT_EXIST);
        }
        String memberPassword = member.getPassword();
        if(!Objects.equals(memberPassword, MD5Util.encrypt(password))) {
            throw new MailException(ExceptionEnum.MEMBER_PASSWORD_NOT_EXIST);
        }
        JwtInfo jwtInfo = new JwtInfo();
        BeanUtils.copyProperties(member, jwtInfo);
        String token = JwtUtil.getJwtToken(jwtInfo, 3600);
        return token;
    }

    public void verifyCode(String mobile, String code) {
        String RCode = (String) redisTemplate.opsForValue().get(SMS_SIGN + mobile);
        if(StringUtils.isEmpty(RCode)) {
            throw new MailException(ExceptionEnum.MEMBER_CODE_NOT_EXIST);
        } else if(!StringUtils.equals(code, RCode)) {
            throw new MailException(ExceptionEnum.MEMBER_CODE_ERROR);
        }
    }

    public boolean verifyMobile(String mobile) {
        MemberEntity count = baseMapper.selectOne(new QueryWrapper<MemberEntity>().eq("mobile", mobile));
        return Objects.isNull(count);
    }

    public boolean verifyUserName(String username) {
        MemberEntity count = baseMapper.selectOne(new QueryWrapper<MemberEntity>().eq("username", username));
        return Objects.isNull(count);
    }

}